package trival.selector;

import NIO.ByteBufferUtil;
import io.netty.channel.ServerChannel;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

//由上面server的例子
//selector的好处，显而易见
//把对多个socket进行监听的工作，都转移到一个线程上，当没任何事件发生的时候，select阻塞，当有事件触发，就可以立即拿来处理
//即减少了没必要的循环检查事件，浪费cpt，又避免了开多个线程并阻塞

public class server_selector {
    public static void main(String[] args) throws IOException {
        Selector selector=Selector.open();
        ServerSocketChannel ssc=ServerSocketChannel.open();
        ssc.bind(new InetSocketAddress(8080));
        ssc.configureBlocking(false);
        SelectionKey register = ssc.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            System.out.println("select");
            //通过selector
            //把多个socket，和对应的监听的事件，绑定在selector上
            //当没有任何事件的时候，select阻塞，当有事件发生的时候，进行处理
            selector.select();
            System.out.println("discover the event");

            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();
                if (key.isAcceptable()){
                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();
                    SocketChannel sc= channel.accept();
                    System.out.println(sc);
                    sc.configureBlocking(false);
                    sc.register(selector,SelectionKey.OP_READ);
                }else if (key.isReadable()){
                    //这里有个小问题，不取消的话，会一直监听到这个事件
                    //不知道为啥，先不管了，直接取消了
                    SocketChannel channel =(SocketChannel) key.channel();
                    ByteBuffer byteBuffer=ByteBuffer.allocate(16);
                    int read = channel.read(byteBuffer);
                    key.cancel();
                }
            }
        }
    }
}
